import pyautogui
import tkinter as tk
from PIL import ImageGrab
import colorsys
import screeninfo  # 需要安装：pip install screeninfo


class ColorDetector:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("智能颜色检测器 - 安全坐标版")

        # ============== 自动获取屏幕分辨率 ==============
        try:
            primary_monitor = screeninfo.get_monitors()[0]
            self.screen_width = primary_monitor.width
            self.screen_height = primary_monitor.height
        except:
            # 保底方案：使用常见分辨率
            self.screen_width = 1920
            self.screen_height = 1080
            print("警告：无法获取屏幕信息，使用默认分辨率 1920x1080")

        # ============== 安全检测区域（屏幕中心区域） ==============
        self.detect_size = 100  # 检测区域边长（像素）
        self.detect_left = self.screen_width // 2 - self.detect_size // 2
        self.detect_top = self.screen_height // 2 - self.detect_size // 2
        self.detect_right = self.detect_left + self.detect_size
        self.detect_bottom = self.detect_top + self.detect_size
        self.detect_center_x = (self.detect_left + self.detect_right) // 2
        self.detect_center_y = (self.detect_top + self.detect_bottom) // 2

        # 快捷键绑定
        self.root.bind('<Control-s>', self.set_target_color)
        self.root.bind('<Control-S>', self.set_target_color)

        # 状态变量
        self.target_hsv = None
        self.h_tolerance = 15
        self.s_tolerance = 30
        self.v_tolerance = 40
        self.detecting = False

        # 初始化UI
        self.setup_ui()

    def setup_ui(self):
        # 状态显示
        status_header = f"屏幕分辨率: {self.screen_width}x{self.screen_height}\n"
        status_header += f"检测区域: [{self.detect_left}, {self.detect_top}] -> [{self.detect_right}, {self.detect_bottom}]\n"
        self.status_label = tk.Label(
            self.root,
            text=status_header + "等待锁定目标颜色 (Ctrl+S)",
            font=('Arial', 12),
            justify='left'
        )
        self.status_label.pack(pady=10)

        # 当前颜色显示框（鼠标位置）
        self.current_color_frame = tk.Frame(self.root, width=100, height=100, relief="groove")
        self.current_color_frame.pack(pady=5)

        # 目标颜色显示框（区域中心）
        self.target_color_frame = tk.Frame(self.root, width=100, height=100, relief="groove")
        self.target_color_frame.pack(pady=5)

        # 容差控制面板
        control_frame = tk.Frame(self.root)
        control_frame.pack(pady=10)

        # 色相容差
        tk.Label(control_frame, text="色相(°):").grid(row=0, column=0)
        self.h_tol_entry = tk.Entry(control_frame, width=5)
        self.h_tol_entry.insert(0, "15")
        self.h_tol_entry.grid(row=0, column=1, padx=5)

        # 饱和度容差
        tk.Label(control_frame, text="饱和度(%):").grid(row=0, column=2)
        self.s_tol_entry = tk.Entry(control_frame, width=5)
        self.s_tol_entry.insert(0, "30")
        self.s_tol_entry.grid(row=0, column=3, padx=5)

        # 明度容差
        tk.Label(control_frame, text="明度(%):").grid(row=0, column=4)
        self.v_tol_entry = tk.Entry(control_frame, width=5)
        self.v_tol_entry.insert(0, "40")
        self.v_tol_entry.grid(row=0, column=5, padx=5)

        # 功能按钮
        tk.Button(control_frame, text="锁定颜色 (Ctrl+S)",
                  command=self.set_target_color).grid(row=1, column=0, columnspan=3, pady=5)
        tk.Button(control_frame, text="开始检测",
                  command=self.toggle_detection).grid(row=1, column=3, columnspan=3)

        # 提示信息
        self.info_label = tk.Label(
            self.root,
            text="鼠标移动查看颜色 | Ctrl+S 锁定区域中心 | Ctrl+C 退出",
            font=('Arial', 10)
        )
        self.info_label.pack(pady=5)

    def rgb_to_hsv(self, rgb):
        """RGB转HSV（0-1范围）"""
        return colorsys.rgb_to_hsv(rgb[0] / 255.0, rgb[1] / 255.0, rgb[2] / 255.0)

    def is_color_in_range(self, current_rgb):
        """颜色匹配逻辑"""
        if not self.target_hsv:
            return False

        current_hsv = self.rgb_to_hsv(current_rgb)
        t_h, t_s, t_v = self.target_hsv
        c_h, c_s, c_v = current_hsv

        # 色相环差异计算
        hue_diff = min(abs(t_h - c_h), 1 - abs(t_h - c_h)) * 360
        # 饱和度/明度差异
        sat_diff = abs(t_s - c_s) * 100
        val_diff = abs(t_v - c_v) * 100

        return (hue_diff <= self.h_tolerance and
                sat_diff <= self.s_tolerance and
                val_diff <= self.v_tolerance)

    def set_target_color(self, event=None):
        """锁定区域中心颜色（带安全验证）"""
        try:
            # 获取坐标并验证
            x, y = self.detect_center_x, self.detect_center_y
            if not (0 <= x < self.screen_width and 0 <= y < self.screen_height):
                raise ValueError(f"无效坐标 ({x}, {y})")

            # 获取颜色
            screenshot = ImageGrab.grab()
            rgb = screenshot.getpixel((x, y))

            # 更新目标颜色
            self.target_hsv = self.rgb_to_hsv(rgb)
            self.h_tolerance = int(self.h_tol_entry.get())
            self.s_tolerance = int(self.s_tol_entry.get())
            self.v_tolerance = int(self.v_tol_entry.get())

            # 更新UI
            hex_color = '#{:02x}{:02x}{:02x}'.format(*rgb)
            self.target_color_frame.config(bg=hex_color)
            status_text = f"目标颜色已锁定 @ 区域中心({x}, {y})\n"
            status_text += f"容差范围: H±{self.h_tolerance}° S±{self.s_tolerance}% V±{self.v_tolerance}%"
            self.status_label.config(text=status_text)

            # 视觉反馈
            self.current_color_frame.config(bg='#4CAF50')  # 绿色成功提示
            self.root.after(200, lambda: self.current_color_frame.config(bg='white'))

        except Exception as e:
            self.status_label.config(text=f"错误: {str(e)}")

    def toggle_detection(self):
        """切换检测状态"""
        if not self.target_hsv:
            self.status_label.config(text="请先锁定目标颜色！")
            return

        self.detecting = not self.detecting
        status = "检测中" if self.detecting else "已停止"
        self.status_label.config(text=f"状态: {status}")

    def update_color(self):
        """实时更新颜色信息"""
        try:
            screenshot = ImageGrab.grab()

            # 显示鼠标位置颜色
            mouse_x, mouse_y = pyautogui.position()
            if 0 <= mouse_x < self.screen_width and 0 <= mouse_y < self.screen_height:
                mouse_rgb = screenshot.getpixel((mouse_x, mouse_y))
                self.current_color_frame.config(bg='#{:02x}{:02x}{:02x}'.format(*mouse_rgb))

            # 检测区域中心颜色
            if self.detecting:
                center_rgb = screenshot.getpixel((self.detect_center_x, self.detect_center_y))
                if self.is_color_in_range(center_rgb):
                    self.root.config(bg="#4CAF50")  # 绿色背景表示匹配成功
                    self.info_label.config(text="★ 颜色匹配成功！ ★")
                else:
                    self.root.config(bg="white")
                    self.info_label.config(text="检测中... | 按Ctrl+C退出")

            self.root.after(50, self.update_color)

        except Exception as e:
            print(f"更新异常: {str(e)}")

    def run(self):
        self.root.after(0, self.update_color)
        self.root.mainloop()


if __name__ == "__main__":
    detector = ColorDetector()
    try:
        detector.run()
    except KeyboardInterrupt:
        print("\n程序已安全退出")